<?php

namespace common\logics\trade;

use Yii;
use yii\db\Exception;
use common\helpers\StringHelper;
use common\helpers\ArrayHelper;
use common\models\trade\Trade;
use common\models\trade\TradeRefund;

/**
 * 交易逻辑操作模型
 *
 * @author emhome <emhome@163.com>
 * @since 1.0
 */
class TradeLogic extends Trade {

 
    /**
     * 根据外部商户订单号查询累计支付、累计退款以及剩余可退现金/积分
     * @param string $bizno
     * @return array
     */
    public function findPayByBizno($bizno) {
        $data = [
            'pay' => [
                'cash' => 0,
                'credit' => 0,
                'total' => 0,
            ],
            'reduce' => [
                'cash' => 0,
                'credit' => 0,
                'total' => 0,
            ],
            'diff' => [
                'cash' => 0,
                'credit' => 0,
                'total' => 0,
            ],
            'paymode' => ''
        ];
        //支付交易单
        $tradePay = static::findOne([
            'bizno' => $bizno,
            'status' => self::STATUS_SUCCESS,
            'balance' => self::BALANCE_PAYMENT
        ]);
        if (!empty($tradePay)) {
            $data['pay']['total'] = $tradePay->total;
            $data['pay']['credit'] = $tradePay->credit;
            $data['pay']['cash'] = $tradePay->cash;
            $data['paymode'] = $tradePay->paymode;
        }

        //累计退款
        $tradeRefunds = TradeRefund::find()
        ->andFilterWhere(['from_trade_no' => $tradePay->trade_no])
        ->andFilterWhere(['>', 'status', TradeRefund::STATUS_WAITPAY])
        ->all();

        foreach ($tradeRefunds as $tradeRefund) {
            $data['reduce']['total'] += $tradeRefund->total;
            $data['reduce']['cash'] += $tradeRefund->cash;
            $data['reduce']['credit'] += $tradeRefund->credit;
        }

        $data['diff']['cash'] = $data['pay']['cash'] - $data['reduce']['cash'];
        $data['diff']['credit'] = $data['pay']['credit'] - $data['reduce']['credit'];
        $data['diff']['total'] = $data['pay']['total'] - $data['reduce']['total'];

        return $data;
    }

    /**
     * Finds order by bizno
     *
     * @param string $bizno
     * @return static|null
     */
    public static function cancelExpired($uid, &$msg) {
        $trades = static::find()->andWhere([
            'and',
            ['user_id' => $uid],
            [
                'status' => [
                    static::STATUS_DEFAULT,
                    static::STATUS_WAITPAY
                ]
            ],
            ['<', 'expire_time', time()]
        ])->all();
        if (empty($trades)) {
            return true;
        }
        //取消所有未支付交易
        $transaction = Yii::$app->db->beginTransaction();
        try {
            //关闭所有
            foreach ($trades as $trade) {
                $trade->status = Trade::STATUS_CENCELED;
                $trade->setMark('交易过期，系统自动取消当前交易');
                //取消积分支付的交易并回滚用户账户积分
                foreach ($trade->paymentOrder as $order) {
                    $rollbackOrder = new TradeOrder();
                    $rollbackOrder->attributes = [
                        'trade_id' => $order->trade_id,
                        'original_no' => $order->original_no,
                        'paymode' => $order->paymode,
                        'pay_type' => $order->pay_type,
                        'pay_no' => $order->pay_no,
                        'currency' => $order->currency,
                        'pay' => $order->pay,
                        'pay_time' => time(),
                        'balance' => TradeOrder::BALANCE_REFUND,
                        'expire_time' => time(),
                    ];
                    $credit = false;
                    if ($order->paymode == self::PAYMODE_CREDIT) {
                        //回滚成功修改退还订单
                        $rollbackOrder->status = TradeOrder::STATUS_SUCCESS;
                        $credit = $order->pay * 10;
                    }
                    if (!$rollbackOrder->save()) {
                        throw new \yii\db\Exception('账户积分支付失败！' . print_r($rollbackOrder->errors, true));
                    }
                    if ($credit !== false) {
                        //回滚账户积分
                        $account = $trade->buyer->account;
                        $account->credit += $credit;
                        $account->updated_at = date('Y-m-d H:i:s');
                        if (!$account->save()) {
                            throw new Exception('账户积分回滚失败！' . print_r($account->errors, true));
                        }
                        //创建回滚积分日志
                        $creditLog = new \common\models\original\UserAccountLogs();
                        $creditLog->attributes = [
                            'user_id' => $trade->user_id,
                            'type' => 'credit',
                            'amount' => $credit,
                            'current' => $account->credit,
                            'ip' => Yii::$app->request->userIP,
                            'mark' => '【订单过期，系统自动取消订单】' . $trade->subject,
                            'detail' => 'trade_order',
                            'detail_id' => $rollbackOrder->id,
                        ];
                        if (!$creditLog->save()) {
                            throw new Exception('积分日志更新失败！' . print_r($creditLog->errors, true));
                        }
                    }
                }
                if (!$trade->save()) {
                    throw new \yii\db\Exception('交易保存失败！' . print_r($trade->errors, true));
                }
            }
            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $msg = $e->getMessage();
            return false;
        }
        return true;
    }

    /**
     * Finds order by bizno
     *
     * @param string $bizno
     * @return static|null
     */
    public static function cancelByBizno($bizno, &$msg) {
        $trades = static::find()
        ->where(['bizno' => $bizno])
        ->andWhere([
            'status' => [
                static::STATUS_DEFAULT,
                static::STATUS_WAITPAY
            ]
        ])
        ->all();
        if (empty($trades)) {
            return true;
        }
        //取消所有未支付交易
        $transaction = Yii::$app->db->beginTransaction();
        try {
            //关闭所有
            foreach ($trades as $trade) {
                $trade->status = Trade::STATUS_CENCELED;
                $trade->setMark('待产生新交易，系统自动取消当前交易');
                //取消积分支付的交易并回滚用户账户积分
                foreach ($trade->paymentOrder as $order) {
                    $rollbackOrder = new TradeOrder();
                    $rollbackOrder->attributes = [
                        'trade_id' => $order->trade_id,
                        'original_no' => $order->original_no,
                        'paymode' => $order->paymode,
                        'pay_type' => $order->pay_type,
                        'pay_no' => $order->pay_no,
                        'currency' => $order->currency,
                        'pay' => $order->pay,
                        'pay_time' => time(),
                        'balance' => TradeOrder::BALANCE_REFUND,
                        'expire_time' => time(),
                    ];
                    $credit = false;
                    if ($order->paymode == self::PAYMODE_CREDIT) {
                        //回滚成功修改退还订单
                        $rollbackOrder->status = TradeOrder::STATUS_SUCCESS;
                        $credit = $order->pay * 10;
                    }
                    if (!$rollbackOrder->save()) {
                        throw new \yii\db\Exception('账户积分支付失败！' . print_r($rollbackOrder->errors, true));
                    }
                    if ($credit !== false) {
                        //回滚账户积分
                        $account = $trade->buyer->account;
                        $account->credit += $credit;
                        $account->updated_at = date('Y-m-d H:i:s');
                        if (!$account->save()) {
                            throw new Exception('账户积分回滚失败！' . print_r($account->errors, true));
                        }
                        //创建回滚积分日志
                        $creditLog = new \common\models\original\UserAccountLogs();
                        $creditLog->attributes = [
                            'user_id' => $trade->user_id,
                            'type' => 'credit',
                            'amount' => $credit,
                            'current' => $account->credit,
                            'ip' => Yii::$app->request->userIP,
                            'mark' => '取消购买' . $trade->subject,
                            'detail' => 'trade_order',
                            'detail_id' => $rollbackOrder->id,
                        ];
                        if (!$creditLog->save()) {
                            throw new Exception('积分日志更新失败！' . print_r($creditLog->errors, true));
                        }
                    }
                }
                //如交易订单过期则关闭当前交易
                if ($trade->expire_time < time()) {
                    $trade->status = Trade::STATUS_CLOSED;
                    $trade->setMark('订单过期失效关闭当前交易');
                }
                if (!$trade->save()) {
                    throw new \yii\db\Exception('账户积分支付失败！' . print_r($trade->errors, true));
                }
            }
            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $msg = $e->getMessage();
            return false;
        }
        return true;
    }

}
